#include <iostream>
#include <stdio.h>
#include <string>
#include <string.h>
#include <windows.h>
#include "stu.h"
//题目1:学生成绩管理程序
 
int main() {
	struct Student Stu[100];//定义一个学生信息结构体数组 
	char Choice = '-1';//用户选择功能 
	int a = 0; 
	int *cnt;

	for(int i = 0; i < 100; i++)//遍历结构体数组赋初值 
	{
		char string[] = "0"; 
		
		Stu[i].s_nAge = 0;
		Stu[i].s_nChinese = 0;
		Stu[i].s_nClass = 0;
		Stu[i].s_nComputer = 0;
		Stu[i].s_nEnglish = 0;
		Stu[i].s_nHistory = 0;
		Stu[i].s_nMath = 0;
		strcpy(Stu[i].s_sId,string);
		strcpy(Stu[i].s_sName,string);
	}
	cnt = &a; 
	
	ShowMenu();//显示主菜单 

	while (Choice != '0')
	{	
		scanf("%c",&Choice);//获取用户输入的按键 
		
		getchar();

		switch(Choice)
		{
			case '1'://录入学生信息
			{
				int b = *cnt;
				int n;
				int argument1 = 1;
				
				printf("请输入需要录入学生的的信息:\n");
	
			for(int i = 0;argument1; i++)
			{
				int argument2 = 1;
				
				printf("学生姓名:");
				scanf("%19s",&Stu[b].s_sName);//从键盘获取学生信息
				printf("\n");
				
				printf("学生学号:");
				scanf("%10s",&Stu[b].s_sId);
				printf("\n");
				
				printf("学生班级:");
				scanf("%d",&Stu[b].s_nClass);
				printf("\n");
				
				printf("学生年龄:");
				scanf("%d",&Stu[b].s_nAge);
				printf("\n");
				
				printf("第%d位学生基本信息录入成功！\n\n",i+1);		
					
				b++;//循环结束，结构体数组下标增加
				printf("您还需要继续输入吗?\n");
				printf("1.继续输入\n");
				printf("2.输入完毕\n");
				printf("请输入:");
				
				while(argument2)//当n=1时此循环结束。n=2时for循环结束 
				{
				
					scanf("%d",&n);
					
					if( n != 1 && n != 2)
					{
						printf("输入错误，请输入1或2:");
					}
					else if(n == 2)
					{
						argument2 = 0;
						argument1 = 0;
					}
					else if(n == 1)
					{
						argument2 = 0;
					} 
				}
			}
				
				printf("\n");
				
				cnt = &b;
				
				printf("已成功录入输入的所有学生信息\n");
				
				break;
			}
			case '2'://增加学生信息
			{
				*cnt += 1;//接着上一位数组下标加一 

				if ( *cnt < 100)//判断结构体数组是否溢出 
				{
					char id[11];//学号 
					int age;//年龄 
					char name[30];//名字 
					int Class;//班级 
					int n;//录入学生数量 
					
					printf("请输入需要增加学生的数量:");
					
					scanf("%d",&n);
					
					printf("\n");

					for (int i=0; i<n; i++)//从已有的学生基础上往后添加学生基本信息 
					{
						printf("学生姓名:");
						scanf("%19s",&Stu[*cnt].s_sName);//从键盘获取学生信息 
						printf("\n");
						
						printf("学生学号:");
						scanf("%10s",&Stu[*cnt].s_sId);
						printf("\n");
						
						printf("学生班级:");
						scanf("%d",&Stu[*cnt].s_nClass); 
						printf("\n");
						
						printf("学生年龄:");
						scanf("%d",&Stu[*cnt].s_nAge);
						printf("\n");

						printf("\n");
						printf("录入成功\n");
						
						*cnt += 1;//循环结束，结构体数组下标增加
					}
					
					printf("\n");
					printf("已成功添加学生信息\n");
					
					break;
				}
			}
			case '3'://删除学生信息
			{
				RemoveStudent(cnt,Stu);//将学生数量指针和结构体数组传入函数 
				
				break;
			}
			case '4'://修改学生基本信息 
			{
				Modify(Stu);//将结构体数组传入函数 
				
				break;
			}
			case '5'://学生单科成绩录入
			{
				EnterGrade(Stu);//将结构体数组传入函数 
				break;	
			} 
			case '6'://查询班级单科成绩排名
			{
				SearchClassRank(cnt,Stu);//将学生数量指针和结构体数组传入函数 
				
				break;
			}
			case '7'://查询某学生信息 
			{
				SearchInformation(Stu);//将结构体数组传入函数 
				
				break;
			}
			case '8'://统计所有科目不及格超过2科的学生名单
			{
				Print(cnt,Stu);//将学生数量指针和结构体数组传入函数 
				
				break;
			}
			case '0'://退出系统 
			{
				printf("您已退出系统，感谢您的使用！");
				 
				Save(*cnt,Stu);//保存录入的学生信息 
				
				exit(0);//退出 
				
			}
			default:
			{
			printf("您的输入有误，请重新输入:\n");

			continue;
			}

		}
		fflush(stdin);//清除缓冲区 
				
		ShowMenu();//弹出主菜单为下次输入提示 
	}
	
	return 0;
}
int SearchID(char a[],struct Student Stu[])//搜寻学生学号的函数 
{
	for(int i = 0; i < 100 || strcmp(Stu[i-1].s_sId,a) == 0; i++)
	{
		if(strcmp(Stu[i].s_sId,a) == 0)
		{
			return i;//返回搜寻到的学生在结构体里的位置i 
		}
	}
	return -1;//没找到返回-1 
}

void Rank(int Class,int subject,int a[],int length,int *p,struct Student Stu[])//某班级单科成绩存入数组 
{
	for(int i = 0,j = 0;i < *p;i++)//将Stu[100]里符合条件的传给a[] 
	{
		if(Stu[i].s_nClass == Class)//5种情况对应不同的科目 
		{
			if(subject == 1)
			{
				a[j] = Stu[i].s_nMath;
				
				j++;
			}
			else if(subject == 2)
			{
				a[j] = Stu[i].s_nChinese;
				
				j++;
			}
			else if(subject == 3)
			{
				a[j] = Stu[i].s_nEnglish;
				
				j++;
			}
			else if(subject == 4)
			{
				a[j] = Stu[i].s_nComputer;
				
				j++;
			}
			else if(subject == 5)
			{
				a[j] = Stu[i].s_nHistory;
				
				j++;
			}
		}
	}
}

int Remove(char a[],int *p,struct Student Stu[])//删除学生信息的函数 
{	
	int index;
	
	index = SearchID(a,Stu);//得到该学生在结构体数组里的位置 
	
	if(index == -1)//没找到就退出此函数 
	{
		return 0; 
	}
	 
	for(int a = index,j = index + 1; a < *p ; a++, j++)//将该学生以后的数组全都往移位一个 
	{
		strcpy(Stu[a].s_sName,Stu[j].s_sName);
		strcpy(Stu[a].s_sId,Stu[j].s_sId);
		Stu[a].s_nClass = Stu[j].s_nClass;
		Stu[a].s_nAge = Stu[j].s_nAge;
	}
	*p = *p -1;
	
	return 1;
}

void ShowMenu()//展示主菜单的函数 
{
printf("\t\t*********************************************\n");
printf("\t\t**                                         **\n");
printf("\t\t**        欢迎使用学生成绩管理程序         **\n");
printf("\t\t**                                         **\n");
printf("\t\t**               (我是菜单)                **\n");
printf("\t\t**                                         **\n");
printf("\t\t**             以下是全部功能              **\n");
printf("\t\t**                                         **\n");
printf("\t\t**           1.录入学生基本信息            **\n");
printf("\t\t**                                         **\n");
printf("\t\t**           2.添加学生基本信息            **\n");
printf("\t\t**                                         **\n");
printf("\t\t**            3.删除学生信息               **\n");
printf("\t\t**                                         **\n");
printf("\t\t**           4.修改学生基本信息            **\n");
printf("\t\t**                                         **\n");
printf("\t\t**           5.学生单科成绩录入            **\n");
printf("\t\t**                                         **\n");
printf("\t\t**         6.查询班级单科成绩排名          **\n");
printf("\t\t**                                         **\n");
printf("\t\t**    7.查询某学生各科的成绩及基本信息     **\n");
printf("\t\t**                                         **\n");
printf("\t\t**  8.统计所有科目不及格超过2科的学生名单  **\n");
printf("\t\t**                                         **\n");
printf("\t\t**       0.退出菜单(保存数据并退出)        **\n");
printf("\t\t*********************************************\n\n");
printf("您需要做什么？(输入对应的按键):");
	
}

void Save(int a,struct Student Stu[])//将学生数据存入文件中的函数 
{
	FILE *fp = fopen("stu.txt","w+");
	
	for (int i = 0; i < a; i++)
	{
		fprintf(fp,"%s %s %d %d %d %d %d %d %d",Stu[i].s_sName,Stu[i].s_sId,Stu[i].s_nAge,Stu[i].s_nClass,Stu[i].s_nMath,Stu[i].s_nEnglish,Stu[i].s_nChinese,Stu[i].s_nComputer,Stu[i].s_nHistory);
	}
	
	fclose(fp);
}

void SearchInformation(struct Student Stu[])//查询学生信息的函数 
{
	char id[11];
	int i = 0;
	int argument = 1;
			
	printf("请输入要查询学生的学号:");
	
	scanf("%s",id);
	printf("\n"); 
	
	for (i;i < 100; i++)//遍历结构体数组找到这个学生并输出他的信息 
	{
		if (strcmp(Stu[i].s_sId,id) == 0)
		{
			printf("此为学生的各科成绩分别为:\n\n");
			printf("数学:%d\n\n",Stu[i].s_nMath);
			printf("语文:%d\n\n",Stu[i].s_nChinese);
			printf("英语:%d\n\n",Stu[i].s_nEnglish);
			printf("计算机:%d\n\n",Stu[i].s_nComputer);
			printf("历史:%d\n\n",Stu[i].s_nHistory);
			printf("基本信息为:\n");
			printf("姓名:%s\n\n",Stu[i].s_sName);
			printf("学号:%s\n\n",Stu[i].s_sId);
			printf("年龄:%d\n\n",Stu[i].s_nAge);
			printf("班级:%d\n\n",Stu[i].s_nClass);
			
			argument = 0;
			i = 101;
		}
	}
	if ( i == 100)
	{
		printf("未找到此学生\n");
	}
}
void RemoveStudent(int *p,struct Student Stu[])//移除学生信息函数 
{
	char id[11];
	int num = 0;
	
	printf("请输入要删除学生的学号:");
	
	scanf("%s",&id);
	
	num = Remove(id,p,Stu);//判断此学生是否被删除 
	
	if (num == 1)
	{
		printf("此学生已删除\n");
	}
	
	else
	{
		printf("此学生不存在\n");
	}
				
}
void Modify(struct Student Stu[])//修改学生信息的函数 
{
	char id[11];
	int i = 0;
	int argument = 1;//用来结束循环的变量 
	
	while(argument)
	{
		printf("请输入需要修改学生的学号:");
		
		scanf("%s",&id);
		
		printf("\n");
		
		i = SearchID(id,Stu);//判断该学生是否被找到 
		
		if(i == -1)
		{
			printf("未找到此学生\n");
		}
		else
		{
			argument = 0;
		}
	}

	printf("此学生姓名为:%s\n",Stu[i].s_sName);
	printf("修改为:");
	scanf("%s",&Stu[i].s_sName);
	printf("\n");
	
	printf("此学生学号为:%s\n",Stu[i].s_sId);
	printf("修改为:");
	scanf("%s",&Stu[i].s_sId);
	printf("\n");
	
	printf("此学生年龄为:%d\n",Stu[i].s_nAge);
	printf("修改为:");
	scanf("%d",&Stu[i].s_nAge);
	printf("\n");
	
	printf("此学生班级为:%d\n",Stu[i].s_nClass);
	printf("修改为:");
	scanf("%d",&Stu[i].s_nClass);
	printf("\n");
	
	printf("修改完毕\n");
}
void SearchClassRank(int *p,struct Student Stu[])//查询某班级单科成绩排名的函数 
{
	int Class;
	int subject;
	int length = 0;//作为数组a的个数 
	int o = 0;//计数器 
	int a[length];//存储单科成绩的数组
	int temp = 0;//用来储存成绩的变量 
	int argument = 1;//结束循环的变量 
	
	printf("请输入要查询的班级:");
	
	scanf("%d",&Class);
	
	for (int t=0; t<100; t++)//给o赋值传给length 
	{
		if (Stu[t].s_nClass == Class)
		{
			o++;
		}	
	}
		
	length = o;
	 
	printf("\n");
	printf("请输入需要查询排名的科目:\n");
	printf("1.数学 2.语文 3.英语 4.计算机 5.历史\n");
	
	while (argument)//冒泡排序法从大到小将成绩排序 
	{
		scanf("%d",&subject);
		
		if (subject > 0 && subject < 6)
		{
			Rank(Class,subject,a,length,p,Stu);
			
			for(int i = 0; i < *p - 1; i++)
			{
				for(int j = 0; j < *p - i - 1; j++)
				{
					if(a[j] < a[j+1])
					{
						temp = a[j];
						a[j] = a[j+1];
						a[j+1] = temp;
					}
				}
			}
		
		if (subject == 1)
		{ 
			printf("%d班数学成绩排名为:\n",Class);
			
			for (int n = 0; n < length; n++)
			{
				printf("No.%d:%d分\n",n+1,a[n]);
			}
		} 
		
		else if (subject == 2)
		{
			printf("%d班语文成绩排名为:\n",Class);
			
			for (int n = 0; n < length; n++)
			{
				printf("No.%d:%d\n",n+1,a[n]);
			}
		}
		
		else if (subject == 3)
		{
			printf("%d班英语成绩排名为:\n",Class);
			
			for (int n = 0; n < length; n++)
			{
				printf("No.%d:%d\n",n+1,a[n]);
			}
		}
		
		else if (subject == 4)
		{
			printf("%d班计算机成绩排名为:\n",Class);
			
			for (int n = 0; n < length; n++)
			{
				printf("No.%d:%d\n",n+1,a[n]);
			}
		}
		
		else if (subject == 5)
		{
			printf("%d班历史成绩排名为:\n",Class);
			
			for (int n = 0; n < length; n++)
			{
				printf("No.%d:%d\n",n+1,a[n]);
			}
		}
		argument = 0;                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    
		}
		else
		{
			printf("输入错误，请重新输入:");
			
			continue;	
		}
			
		}
}
void Print(int *p,struct Student Stu[])//打印不及格成绩超过两科的名单 
{
	printf("名单如下:\n");
	for (int i = 0,index = 0; i < *p; i++)
	{
		if (Stu[i].s_nChinese < 60)
		{
			index++;
		}
		if (Stu[i].s_nComputer < 60)
		{
			index++; 
		}
		if (Stu[i].s_nEnglish < 60)
		{
			index++; 
		}
		if (Stu[i].s_nHistory < 60)
		{
			index++; 
		}
		if (Stu[i].s_nMath < 60)
		{
			index++; 
		}
		if (index > 2)
		{
			printf("%d班:%s\n\n",Stu[i].s_nClass,Stu[i].s_sName);
		}
	}
	
}
void EnterGrade(struct Student Stu[])//录入学生单科成绩的函数 
{
	int choice = 0;
	int Class = 0;
	int subject = 0;
	int grade = 0;
	char id[11];
	int receiver;
	
	printf("请选择:\n");
	printf("1.按班级录入学生单科成绩\n");
	printf("2.输入学号录入学生单科成绩\n");
	printf("请输入:");
	scanf("%d",&choice);
	
	if(choice == 2)
	{
		printf("请输入学号:");
		scanf("%s",&id);
		 
		receiver = SearchID(id,Stu);
		
		printf("学生姓名:%s\n",Stu[receiver].s_sName);
		printf("数学成绩:");
		scanf("%d",&Stu[receiver].s_nMath);
		printf("\n");
		
		printf("英语成绩:");
		scanf("%d",&Stu[receiver].s_nEnglish);
		printf("\n");
		
		printf("语文成绩:");
		scanf("%d",&Stu[receiver].s_nChinese);
		printf("\n");
		
		printf("计算机成绩:");
		scanf("%d",&Stu[receiver].s_nComputer);
		printf("\n");
		
		printf("历史成绩:");
		scanf("%d",&Stu[receiver].s_nHistory);
		printf("\n");
		
	}
	else if(choice == 1)
	{
		printf("请输入需要录入单科成绩的班级:\n");
		scanf("%d",&Class);
		
		printf("请问您需要录入的单科成绩是:\n");
		printf("1.数学 2.英语 3.语文 4.计算机 5.历史\n") ;
		printf("请输入:");
		scanf("%d",&subject);
		
		for(int i = 0; i < 100; i++)//遍历,再用Switch分情况录入 
		{
			if(Stu[i].s_nClass == Class)
			{
				printf("姓名：%s\n",Stu[i].s_sName);
				printf("录入成绩为:");
				scanf("%d",&grade);
				printf("\n");
				
				switch(subject)
				{
					case 1:
						{
							Stu[i].s_nMath = grade;
							break;
						}
					case 2:
						{
							Stu[i].s_nEnglish = grade;
							break;
						}
					case 3:
						{
							Stu[i].s_nChinese = grade;
							break;
						}
					case 4:
						{
							Stu[i].s_nComputer = grade;
							break;
						}
					case 5:
						{
							Stu[i].s_nHistory = grade;
							break;
						}			
				}
			}
		}
	}
}